package com.xuxiao.simple;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpServerCodec;


public class FirstStudyNettyServerTest {

    /**
     * The handler specified here will always be evaluated by a newly accepted Channel.
     * The ChannelInitializer is a special handler that is purposed to help a user configure a new Channel.
     * It is most likely that you want to configure the ChannelPipeline of the new Channel
     * by adding some handlers such as DiscardServerHandler to implement your network application.
     * As the application gets complicated,
     * it is likely that you will add more handlers to the pipeline and extract this anonymous class into a top-level class eventually
     */
    private static ChannelInitializer<SocketChannel> channelInitializer =  new ChannelInitializer<SocketChannel>() {
        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            ChannelPipeline pipeline = ch.pipeline();
            HttpServerCodec httpServerCodec = new HttpServerCodec();
            pipeline.addLast("HttpServerCodec",httpServerCodec);
            pipeline.addLast(new SimpleImpl());
        }
    };

    public static void main(String[] args) throws Exception {
        // 处理accept
        EventLoopGroup boss = new NioEventLoopGroup();
        // 实际处理业务
        EventLoopGroup worker = new NioEventLoopGroup();
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(boss,worker)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG,128)
                    .childOption(ChannelOption.SO_KEEPALIVE,true)
                    .childHandler(channelInitializer);

            ChannelFuture sync = serverBootstrap.bind(36963).sync();

            System.out.println(sync);
            // 让他一直等在这里
            sync.channel().closeFuture().sync();
        } finally {
            // 其实不管是NioEventLoop 还是什么 最终都继承自 SingleThreadEventExecutor
            // 从而一个个的关闭  其实这里关闭的是Selector
            // 另外 boss 和 worker 的关闭流程其实是一样的
            boss.shutdownGracefully();
            worker.shutdownGracefully();
        }

    }

}
